﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SCMS.CoreBusinessLogic.PurchaseOrder;
using SCMS.CoreBusinessLogic.Web;
using SCMS.UI.Models;
using SCMS.Model;
using System.Data.Objects.DataClasses;
using SCMS.CoreBusinessLogic.TenderAnalysis;
using SCMS.CoreBusinessLogic.OrderRequest;
using SCMS.CoreBusinessLogic.ActionFilters;
using SCMS.CoreBusinessLogic.Security;
using SCMS.CoreBusinessLogic.NotificationsManager;
using SCMS.CoreBusinessLogic._ExchangeRate;
using SCMS.CoreBusinessLogic._Supplier;
using System.Text;
using SCMS.CoreBusinessLogic._Location;
using SCMS.Resource;
using SCMS.UI.GeneralHelper;

namespace SCMS.UI.Controllers
{
    [MyException]
    //[SessionExpireFilter]
    public class PurchaseOrderController : PortalBaseController
    {
        private IPurchaseOrderService POService;
        private ITAnalysisService TAService;
        private IOrderRequest ORService;
        private INotificationService notificationService;
        private IExchangeRateService exchangeRateService;
        private ISupplierService supplierService;
        private ILocationService locationService;

        public PurchaseOrderController(IPermissionService permissionService, IUserContext userContext, IPurchaseOrderService POService, ITAnalysisService TAService, IOrderRequest ORService,
            IExchangeRateService exchangeRateService, INotificationService notificationService, ISupplierService supplierService, ILocationService locationService)
            : base(userContext, permissionService)
        {
            this.POService = POService;
            this.TAService = TAService;
            this.ORService = ORService;
            this.notificationService = notificationService;
            this.exchangeRateService = exchangeRateService;
            this.supplierService = supplierService;
            this.locationService = locationService;
        }
        //
        // GET: /PurchaseOrder/
        //[OutputCache(Duration = 3600, VaryByParam = "none")]
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult ChoosePOTye()
        {
            var model = new ChoosePOType();
            return View(model);
        }

        public ActionResult LoadSelectedPOType(ChoosePOType obj)
        {
            ViewBag.IsSingleQ = obj.IsSingleQuote;
            return View();
        }

        public ActionResult LoadPO()
        {
            return TenderPOView();
        }

        private ActionResult TenderPOView()
        {
            var TAmodel = new POModel()
            {
                POEntiy = new Model.PurchaseOrder { PODate = DateTime.Today, LatestDeliveryDate = DateTime.Today },
                OrderRequests = new SelectList(POService.GetOrderRequests(countryProg.Id), "Id", "RefNumber"),
                TAnalysis = new SelectList(POService.GetTenderAnalysis(countryProg.Id), "Id", "RefNumber"),
                suppliers = new SelectList(TAService.GetSuppliers(countryProg.Id), "Id", "Name"),
                ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description"),
                deliveryAddress = new SelectList(ORService.GetLocations(countryProg.Id), "Id", "Name"),
                PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description"),
                ORTenderItems = new List<POrderTenderItems>(),
                PONumber = string.Format("--{0}--", Resources.Global_String_NewPO)
            };
            ModelState.Clear();
            return View("LoadPO", TAmodel);
        }

        public ActionResult EditPO(Guid Id)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(Id);
            List<BudgetLineView> budgetLines = ORService.GetProjectBugdetLines((Guid)po.ProjectDonorId);
            Models.POModel model = new POModel
            {
                POEntiy = po,
                POItems = new List<POItems>(),
                ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description"),
                deliveryAddress = new SelectList(ORService.GetLocations(countryProg.Id), "Id", "Name"),
                PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description")
            };
            List<Model.PurchaseOrderItem> poItems = POService.GetPurchaseOrderItems(Id);
            foreach (var poItem in poItems)
            {
                model.POItems.Add(new POItems { EntityPOItem = poItem, BudgetLines = new SelectList(budgetLines, "Id", "Description", poItem.BudgetLineId) });
            }
            return View(model);
        }

        public ActionResult UpdatePOTender(Models.POModel model)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(model.POEntiy.Id);
            Model.PurchaseOrderItem poItem;
            po.PODate = model.PODate;
            po.QuotationRef = model.QuatationRef;
            po.LatestDeliveryDate = model.deliveryDate;
            po.DeliveryAddress = model.deliveryAddressID;
            po.Remarks = model.DRCRemarks;
            po.ShippingTermId = model.shippingTerm;
            po.PaymentTermId = model.paymentTerm;
            po.TotalAmount = 0;
            foreach (var item in model.POItems)
            {
                poItem = POService.GetPurchaseOrderItemById(item.EntityPOItem.Id);
                poItem.BudgetLineId = item.BudgetLineId;
                poItem.Quantity = item.Quantity;
                poItem.Remarks = item.Remarks;
                poItem.TotalPrice = item.TotalCost;
                poItem.UnitPrice = item.UnitCost;
                po.TotalAmount += item.TotalCost;
                POService.SaveReviewedPOItem(poItem);
            }
            POService.SaveReviewedPO(po);
            return LoadLastCreateStep(po);
        }

        //[HandleError(ExceptionType = typeof(NullReferenceException), View = "SpecialError")]
        public ActionResult LoadPOrder(Guid id)
        {
            POrderTenderItems TItems;
            List<POrderTenderItems> POItemsList = new List<POrderTenderItems>();
            using (var context = new SCMSEntities())
            {
                Model.TenderAnalysi TA = context.TenderAnalysis.FirstOrDefault(p => p.Id == id);
                Model.Supplier selectedSuplier = context.Suppliers.FirstOrDefault(p => p.Id == TA.SelectedSupplierId);
                Model.ShippingTerm shippingTerm = (from n in context.TenderBidders
                                                   where n.TenderAnalysisId == id & n.SupplierId == TA.SelectedSupplierId
                                                   select n).FirstOrDefault().ShippingTerm;
                Model.PaymentTerm paymentTerm = (from n in context.TenderBidders
                                                 where n.TenderAnalysisId == id & n.SupplierId == TA.SelectedSupplierId
                                                 select n).FirstOrDefault().PaymentTerm;
                Model.Location location = context.Locations.Where(p => p.Id == TA.OrderRequest.FinalDestinationId).First();
                List<Model.TenderBidderQuote> tbQuoteList = (from n in context.TenderBidders
                                                             where n.TenderAnalysisId == TA.Id & n.SupplierId == TA.SelectedSupplierId
                                                             select n).FirstOrDefault().TenderBidderQuotes.ToList();
                decimal? transportCost = selectedSuplier.TenderBidders.FirstOrDefault(t => t.TenderAnalysisId == TA.Id).TransportCost;
                List<BudgetLineView> budgetLines = ORService.GetProjectBugdetLines((Guid)tbQuoteList[0].OrderRequestItem.ProjectBudget.BudgetCategory.ProjectDonorId);

                foreach (TenderBidderQuote item in tbQuoteList)
                {
                    TItems = new POrderTenderItems();
                    TItems.TBQuoteEntity = item;
                    //Model.ProjectBudget bl = context.ProjectBudgets.SingleOrDefault(p => p.Id == item.OrderRequestItem.BudgetLineId);
                    //Round Unit costs
                    item.UnitPrice = Math.Round(item.UnitPrice, 2);
                    TItems.TotalCost = Math.Round((item.OrderRequestItem.Quantity * item.UnitPrice), 2);
                    TItems.BudgetLines = budgetLines;
                    TItems.BudgetLineId = item.OrderRequestItem.BudgetLineId;
                    Item i = item.OrderRequestItem.Item;
                    Model.UnitOfMeasure u = i.UnitOfMeasure;
                    POItemsList.Add(TItems);
                }

                POModel model = new POModel();
                //Add transport cost if it exists.
                if (transportCost.HasValue)
                {
                    POItemsList.Add(new POrderTenderItems
                    {
                        TBQuoteEntity = new TenderBidderQuote(),
                        BudgetLines = budgetLines,
                        TransportDescription = Resources.Global_String_TransportCost,
                        TransportQty = 1,
                        TransportUnitCost = Math.Round(transportCost.Value, 2),
                        TotalCost = Math.Round(transportCost.Value, 2)
                    });
                    model.IncludesTransportCost = true;
                }
                model.POEntiy = new Model.PurchaseOrder();
                model.PODate = DateTime.Today;
                model.OrderRequests = new SelectList(POService.GetOrderRequests(countryProg.Id), "Id", "RefNumber", TA.OrderRequest);
                model.ORID = TA.OrderRequest.Id;
                model.TAnalysis = new SelectList(POService.GetTenderAnalysis(countryProg.Id), "Id", "RefNumber", TA);
                model.TAID = TA.Id;
                model.suppliers = new SelectList(TAService.GetSuppliers(countryProg.Id), "Id", "Name", selectedSuplier);
                model.supplierID = selectedSuplier.Id;
                if (shippingTerm != null)
                {
                    model.ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description", shippingTerm);
                    model.shippingTerm = shippingTerm.Id;
                }
                else model.ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description");

                model.deliveryAddress = new SelectList(ORService.GetLocations(countryProg.Id), "Id", "Name", location);
                model.deliveryAddressID = location.Id;
                model.deliveryDate = tbQuoteList[0].TenderBidder.DeliveryTime != null ? tbQuoteList[0].TenderBidder.DeliveryTime.Value : DateTime.Now;
                if (paymentTerm != null)
                {
                    model.PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description", paymentTerm);
                    model.paymentTerm = paymentTerm.Id;
                }
                else model.PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description");
                model.ORTenderItems = POItemsList;
                model.PONumber = string.Format("--{0}--", Resources.Global_String_NewPO);
                ViewBag.Currency = TA.OrderRequest.Currency.ShortName;
                ViewBag.CurrencyId = TA.OrderRequest.CurrencyId;
                ViewBag.ProjectNo = TA.OrderRequest.ProjectDonor.ProjectNumber;
                return View("LoadPO", model);
            }
        }

        public ActionResult LoadSingleQ()
        {
            return SingleQView();
        }

        public ActionResult EditSingleQ(Guid Id)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(Id);
            var SingleQmodel = new POSingleQuoteModel()
            {
                POEntiy = po,
                PODate = po.PODate,
                deliveryDate = DateTime.Today,
                Currencies = new SelectList(ORService.GetCurrencies(countryProg.Id), "Id", "ShortName", po.CurrencyId),
                Projects = new SelectList(ORService.GetProject(countryProg.Id), "Id", "Name", po.ProjectDonor.ProjectId),
                ProjectNos = new SelectList(ORService.GetProjectNos(countryProg.Id, po.ProjectDonor.ProjectId), "Id", "ProjectNumber", po.ProjectDonorId),
                suppliers = new SelectList(TAService.GetSuppliers(countryProg.Id), "Id", "Name", po.SupplierId),
                ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description", po.ShippingTermId),
                deliveryAddress = new SelectList(ORService.GetLocations(countryProg.Id), "Id", "Name", po.DeliveryAddress),
                PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description", po.PaymentTermId),
                ORItems = new List<POrderORItems>(),
                PONumber = po.RefNumber,
                ProjectId = po.ProjectDonor.ProjectId,
                ProjectDonorId = po.ProjectDonorId
            };
            return View("LoadSingleQ", SingleQmodel);
        }

        private ActionResult SingleQView()
        {
            var SingleQmodel = new POSingleQuoteModel()
            {
                POEntiy = new Model.PurchaseOrder(),
                PODate = DateTime.Today,
                deliveryDate = DateTime.Today,
                Currencies = new SelectList(ORService.GetCurrencies(countryProg.Id), "Id", "ShortName"),
                Projects = new SelectList(ORService.GetProject(countryProg.Id), "Id", "Name"),
                ProjectNos = new SelectList(ORService.GetProjectNos(countryProg.Id, Guid.Empty), "Id", "ProjectNumber"),
                suppliers = new SelectList(TAService.GetSuppliers(countryProg.Id), "Id", "Name"),
                ShippingTerms = new SelectList(TAService.GetShippingTerms(countryProg.Id), "Id", "Description"),
                deliveryAddress = new SelectList(ORService.GetLocations(countryProg.Id), "Id", "Name"),
                PaymentTerms = new SelectList(TAService.GetPaymentTerms(countryProg.Id), "Id", "Description"),
                ORItems = new List<POrderORItems>(),
                PONumber = string.Format("--{0}--", Resources.Global_String_NewPO)
            };
            return View("LoadSingleQ", SingleQmodel);
        }

        public ActionResult SavePOTender(POModel model)
        {

            Guid poId = Guid.NewGuid(); decimal totalamount = 0;
            if (model.POEntiy.Id.Equals(Guid.Empty))
            {
                using (var dbContext = new SCMSEntities())
                {
                    var ta = dbContext.TenderAnalysis.FirstOrDefault(p => p.Id == model.TAID);
                    model.POEntiy.OrderRequestId = ta.OrderRequestId;
                    model.POEntiy.ProjectDonorId = ta.OrderRequest.ProjectDonorId;
                    model.POEntiy.CurrencyId = ta.OrderRequest.CurrencyId;
                    model.POEntiy.CountryProgrammeId = countryProg.Id;
                    model.POEntiy.PreparedBy = currentStaff.Id;
                }
                model.POEntiy.Id = poId;
                model.POEntiy.CountryProgrammeId = countryProg.Id;
                model.POEntiy.PreparedBy = currentStaff.Id;
                model.POEntiy.PreparedOn = DateTime.Now;
                model.POEntiy.IsAuthorized = false;
                model.POEntiy.IsReviewed = false;
                model.POEntiy.TenderAnalysisId = model.TAID;
                model.POEntiy.ShippingTermId = model.shippingTerm;
                model.POEntiy.PaymentTermId = model.paymentTerm;
            }
            PurchaseOrderItem newPOItem;
            EntityCollection<Model.PurchaseOrderItem> poItems = new EntityCollection<PurchaseOrderItem>();
            int count = 0;
            if (model.IncludesTransportCost)
                count = model.ORTenderItems.Count - 1;
            else
                count = model.ORTenderItems.Count;

            for (int i = 0; i < count; i++)
            {
                newPOItem = new PurchaseOrderItem();
                newPOItem.Id = Guid.NewGuid();
                newPOItem.PurchaseOrderId = poId;
                newPOItem.Quantity = (int)model.ORTenderItems[i].Qunatity;
                newPOItem.UnitPrice = (double)model.ORTenderItems[i].UnitCost;
                newPOItem.BudgetLineId = model.ORTenderItems[i].BudgetLineId;
                newPOItem.Remarks = model.ORTenderItems[i].Remarks;
                newPOItem.TotalPrice = model.ORTenderItems[i].Qunatity * model.ORTenderItems[i].UnitCost;
                newPOItem.TenderBidderQuoteId = model.ORTenderItems[i].TBQuoteEntity.Id;
                newPOItem.OrderRequestItemId = model.ORTenderItems[i].ORItemId;
                totalamount += model.ORTenderItems[i].Qunatity * model.ORTenderItems[i].UnitCost;
                poItems.Add(newPOItem);
            }
            if (model.IncludesTransportCost)
            {
                newPOItem = new PurchaseOrderItem();
                newPOItem.Id = Guid.NewGuid();
                newPOItem.PurchaseOrderId = poId;
                newPOItem.Quantity = 1;
                newPOItem.UnitPrice = (double)model.ORTenderItems[count].TransportUnitCost;
                newPOItem.TotalPrice = (decimal)newPOItem.UnitPrice * newPOItem.Quantity;
                newPOItem.BudgetLineId = model.ORTenderItems[count].BudgetLineId;
                newPOItem.Remarks = model.ORTenderItems[count].TransportRemarks;
                totalamount += newPOItem.TotalPrice;
                poItems.Add(newPOItem);
            }

            model.POEntiy.TotalAmount = totalamount;
            POService.SavePuchaseOrder(model.POEntiy, poItems);

            return LoadLastCreateStep(POService.GetPurchaseOrderById(model.POEntiy.Id));

        }

        public ActionResult SavePOSingleQ(POSingleQuoteModel model)
        {
            if (model.POEntiy.Id.Equals(Guid.Empty))
            {
                model.POEntiy.TotalAmount = 0;
                model.POEntiy.CountryProgrammeId = countryProg.Id;
                model.POEntiy.PreparedBy = currentStaff.Id;
                model.POEntiy.TenderAnalysisId = Guid.Empty;
                model.POEntiy.PreparedOn = DateTime.Now;
                model.POEntiy.IsAuthorized = false;
                model.POEntiy.IsReviewed = false;
            }
            POService.SavePuchaseOrder(model.POEntiy);
            return LoadSingleQItems(model.POEntiy.Id);
        }

        public ActionResult LoadSingleQItems(Guid Id, List<BudgetCheckResult> brcList = null)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(Id);
            List<Model.OrderRequest> orList = POService.GetPOrderORs(Id);
            List<Model.PurchaseOrderItem> poItems;
            Models.POStep2Model model = new POStep2Model { EntityPO = po, POrderORs = new List<POrderOR>(), BudgetCheckResults = brcList };
            Models.POrderOR porderOR;
            foreach (var or in orList)
            {
                porderOR = new POrderOR { EntitiyOR = or, POItems = new List<POItems>() };
                poItems = POService.GetPOItemsByOrId(Id, or.Id);
                if (poItems.Count < 1)
                    continue;
                foreach (var poItem in poItems)
                {
                    porderOR.POItems.Add(new POItems { EntityPOItem = poItem });
                }
                model.POrderORs.Add(porderOR);
            }
            ViewBag.PORefNumber = po.RefNumber;
            return View("LoadSingleQItems", model);
        }

        public ActionResult LoadAddItems(Guid Id)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(Id);
            //Use the TA Service to get Order Requests with unprocessed items
            List<Model.OrderRequest> orList = TAService.GetOrderRequests(countryProg.Id);
            List<Model.OrderRequestItem> orItems;
            Models.POrderOR model = new POrderOR();
            if (orList.Count > 0)
            {
                model.EntitiyOR = orList[0];
                model.OrderRequestId = orList[0].Id;
                model.PoId = Id;
                model.OrderRequests = new SelectList(orList, "Id", "RefNumber", orList[0].Id);
                model.POrderORItems = new List<POrderORItems>();
                orItems = TAService.GetUnprocessedORItems(orList[0].Id);
                foreach (var orItem in orItems)
                {
                    ConvertORItemNumbersToPOCurrency(po, orItem);
                    model.POrderORItems.Add(new POrderORItems
                    {
                        EntityORItem = orItem,
                        AddToPO = true,
                        BudgetLines = new SelectList(ORService.GetProjectBugdetLines((Guid)orList[0].ProjectDonorId), "Id", "Description", orItem.BudgetLineId)
                    });
                }
                model.SameCurrency = po.Currency.Equals(orList[0].Currency);
                ViewBag.POCurrency = po.Currency.ShortName;
            }
            return View("AddPOItems", model);
        }

        private void ConvertORItemNumbersToPOCurrency(Model.PurchaseOrder po, Model.OrderRequestItem orItem)
        {
            orItem.EstimatedUnitPrice = Math.Round((decimal)exchangeRateService.GetForeignCurrencyValue(po.Currency, orItem.OrderRequest.Currency, orItem.EstimatedUnitPrice, countryProg.Id), 2);
            orItem.EstimatedPrice = orItem.EstimatedUnitPrice * orItem.Quantity;
        }

        public ActionResult SelectOR(Models.POrderORSelect mdl)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(mdl.PoId);
            //Use the TA Service to get Order Requests with unprocessed items
            List<Model.OrderRequest> orList = TAService.GetOrderRequests(countryProg.Id);
            Model.OrderRequest selectedOR = null;
            foreach (var or in orList)
                if (or.Id == mdl.OrId)
                    selectedOR = or;
            List<Model.OrderRequestItem> orItems;
            Models.POrderOR model = new POrderOR();
            if (orList.Count > 0)
            {
                if (selectedOR == null)
                    selectedOR = orList[0];
                model.EntitiyOR = selectedOR;
                model.OrderRequestId = selectedOR.Id;
                model.PoId = mdl.PoId;
                model.OrderRequests = new SelectList(orList, "Id", "RefNumber", selectedOR.Id);
                model.POrderORItems = new List<POrderORItems>();
                orItems = TAService.GetUnprocessedORItems(selectedOR.Id);
                foreach (var orItem in orItems)
                {
                    ConvertORItemNumbersToPOCurrency(po, orItem);
                    model.POrderORItems.Add(new POrderORItems
                    {
                        EntityORItem = orItem,
                        AddToPO = true,
                        BudgetLines = new SelectList(ORService.GetProjectBugdetLines(selectedOR.ProjectDonorId.Value), "Id", "Description", orItem.BudgetLineId)
                    });
                }
                model.SameCurrency = po.Currency.Equals(orList[0].Currency);
                ViewBag.POCurrency = po.Currency.ShortName;
            }
            return View("AddPOItems", model);
        }

        public ActionResult AddItemsToPO(POrderOR model)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(model.PoId);
            Model.PurchaseOrderItem poItem;
            if (po.TotalAmount == null)
                po.TotalAmount = 0;
            foreach (var orItem in model.POrderORItems)
            {
                if (orItem.AddToPO)
                {
                    poItem = new PurchaseOrderItem
                    {
                        BudgetLineId = orItem.BudgetLineId,
                        OrderRequestItemId = orItem.EntityORItem.Id,
                        PurchaseOrderId = po.Id,
                        Quantity = (int)orItem.Quantity,
                        Remarks = orItem.Remarks,
                        TotalPrice = orItem.TotalCost,
                        UnitPrice = (double)orItem.UnitCost
                    };
                    po.TotalAmount += orItem.TotalCost;
                    POService.SavePOItem(poItem);
                }
            }
            if (po.OrderRequest == null)
                po.OrderRequestId = model.OrderRequestId;
            POService.SaveReviewedPO(po);
            return LoadSingleQItems(po.Id);
        }

        public ActionResult EditPOItem(Guid Id)
        {
            Model.PurchaseOrderItem poItem = POService.GetPurchaseOrderItemById(Id);
            Models.POItems model = new POItems
            {
                EntityPOItem = poItem,
                BudgetLines = new SelectList(ORService.GetProjectBugdetLines((Guid)poItem.PurchaseOrder.ProjectDonorId), "Id", "Description")
            };
            return View("EditPOItem", model);
        }

        public ActionResult UpdatePOItem(Models.POItems model)
        {
            POService.SavePOItem(model.EntityPOItem);
            return LoadSingleQItems(model.EntityPOItem.PurchaseOrderId);
        }

        public ActionResult DeletePOItem(Guid Id)
        {
            Model.PurchaseOrderItem poItem = POService.GetPurchaseOrderItemById(Id);
            POService.DeletePOItem(poItem);
            return LoadSingleQItems(poItem.PurchaseOrderId);
        }

        public ActionResult LoadOtherPODetails(Models.POStep2Model model)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(model.EntityPO.Id);
            return LoadLastCreateStep(po);
        }

        private ActionResult LoadLastCreateStep(Model.PurchaseOrder po)
        {
            Models.POLastStepModel poModel = new POLastStepModel { POEntiy = po };
            return View("LoadOtherPODetails", poModel);
        }

        public ActionResult Load2ndLastStep(Guid poId)
        {
            return LoadLastCreateStep(POService.GetPurchaseOrderById(poId));
        }

        public ActionResult SubmitPurchaseOrder(Models.POLastStepModel model)
        {
            //Run another check on funds availability
            List<BudgetCheckResult> bcrList = POService.RunFundsAvailableCheck(model.POEntiy.Id);
            if (bcrList.Count > 0)
                return LoadSingleQItems(model.POEntiy.Id, bcrList);//Render PO with message saying funds not sufficient

            Model.PurchaseOrder po = POService.GetPurchaseOrderById(model.POEntiy.Id);
            po.ProformaRequired = model.POEntiy.ProformaRequired;
            po.CommercialInvoiceRequired = model.POEntiy.CommercialInvoiceRequired;
            po.WayBillRequired = model.POEntiy.WayBillRequired;
            po.PackingListRequired = model.POEntiy.PackingListRequired;
            po.DeliveryNoteRequired = model.POEntiy.DeliveryNoteRequired;
            po.ManualsRequired = model.POEntiy.ManualsRequired;
            po.CertificatesReqired = model.POEntiy.CertificatesReqired;
            po.OtherRequired = model.POEntiy.OtherRequired;
            if (po.OtherRequired == true)
                po.OtherSpecify = model.POEntiy.OtherSpecify;
            po.ShippingMarks = model.POEntiy.ShippingMarks;
            po.ConsigneeAddress = model.POEntiy.ConsigneeAddress;
            po.ConsigneeEmail1 = model.POEntiy.ConsigneeEmail1;
            po.ConsigneeEmail2 = model.POEntiy.ConsigneeEmail2;
            po.PrefinancingGuaranteeRequired = model.POEntiy.PrefinancingGuaranteeRequired;
            if (po.PrefinancingGuaranteeRequired == true)
                po.PFGPercentage = model.POEntiy.PFGPercentage;
            POService.SaveReviewedPO(po);
            return LoadAttacheDocs(po.Id);
            ////Morgan, uncomment the line above and remove these lines below except the return statement. Then go to that method and uncomment the commented
            //po.PreparedOn = DateTime.Now;
            //po.PODate = DateTime.Now;
            //po.PreparedBy = currentStaff.Id;
            //po.IsSubmitted = true;
            //po.IsReviewed = po.IsAuthorized = po.IsRejected = false;
            //po.RefNumber = POService.GenerateUniquNumber(countryProg);
            //POService.SaveReviewedPO(po);
            ////Send notification
            //notificationService.SendToAppropriateApprover(NotificationHelper.poCode, NotificationHelper.reviewCode, po.Id);
            //return ViewPurchaseOrders();
        }

        public ActionResult LoadAttacheDocs(Guid docId)
        {
            return View("LoadAttacheDocs", new AttachedDocument() { POEntity = POService.GetPurchaseOrderById(docId), DocList = POService.GetList(docId, countryProg.Id) });
        }

        public ActionResult AttachNewDoc(Guid docId, Guid? attachedDocId = null)
        {
            return View(attachedDocId == null ? new AttachedDocument() { DocumentId = docId, Action = "SaveNewDoc" } : POService.GetDocById((Guid)attachedDocId));
        }

        public ActionResult SaveNewDoc(Model.AttachedDocument model)
        {
            if (UserSession.CurrentSession.UploadedDocDetails == null)
                return AttachNewDoc((Guid)model.DocumentId);
            model.CountryProgrammeId = countryProg.Id;
            model.AttachedBy = currentStaff.Id;
            model.AttachedOn = DateTime.Now;
            model.Id = Guid.NewGuid();
            model.DocumentType = "PO";
            model.FileContent = UserSession.CurrentSession.UploadedDocDetails.FileContent;
            model.FileSize = UserSession.CurrentSession.UploadedDocDetails.ContentLength;
            model.ContentType = UserSession.CurrentSession.UploadedDocDetails.ContentType;
            model.FileName = UserSession.CurrentSession.UploadedDocDetails.FileName;
            POService.Save<AttachedDocument>(model);
            UserSession.CurrentSession.UploadedDocDetails = null;
            return LoadAttacheDocs((Guid)model.DocumentId);
        }

        public ActionResult UpdateAttachedDoc(Model.AttachedDocument model)
        {
            if (UserSession.CurrentSession.UploadedDocDetails != null)
            {
                model.FileContent = UserSession.CurrentSession.UploadedDocDetails.FileContent;
                model.FileSize = UserSession.CurrentSession.UploadedDocDetails.ContentLength;
                model.ContentType = UserSession.CurrentSession.UploadedDocDetails.ContentType;
                model.FileName = UserSession.CurrentSession.UploadedDocDetails.FileName;
            }
            POService.Update<AttachedDocument>(model);
            UserSession.CurrentSession.UploadedDocDetails = null;
            return LoadAttacheDocs((Guid)model.DocumentId);
        }

        public ActionResult DeleteAttachedDoc(Guid attachedDocId, Guid docId)
        {
            POService.DeleteAttachedDoc(attachedDocId);
            return LoadAttacheDocs(docId);
        }

        public ActionResult SubmitPO(Model.AttachedDocument model)
        {
            Model.PurchaseOrder po = POService.GetPurchaseOrderById(model.POEntity.Id);
            po.PreparedOn = DateTime.Now;
            po.PODate = DateTime.Now;
            po.PreparedBy = currentStaff.Id;
            po.IsSubmitted = true;
            po.IsReviewed = po.IsAuthorized = po.IsRejected = false;
            po.RefNumber = POService.GenerateUniquNumber(countryProg);
            POService.SaveReviewedPO(po);
            //Send notification
            notificationService.SendToAppropriateApprover(NotificationHelper.poCode, NotificationHelper.reviewCode, po.Id);
            return ViewPurchaseOrders();
        }

        public ActionResult DeletePO(Guid Id)
        {
            POService.DeletePO(Id);
            return ViewPurchaseOrders();
        }

        public ActionResult ViewPurchaseOrders()
        {
            List<Model.PurchaseOrder> Po = POService.GetPOs(countryProg.Id);
            List<ViewPOs> POmodelist = new List<ViewPOs>();
            ViewPOs model;
            using (var context = new SCMSEntities())
            {
                foreach (PurchaseOrder item in Po)
                {
                    model = new ViewPOs()
                    {
                        POEntiy = item,
                        supplier = context.Suppliers.SingleOrDefault(p => p.Id == item.SupplierId).Name,
                        //paymentTerm = context.PaymentTerms.SingleOrDefault(p => p.Id == item.PaymentTermId).Code
                    };
                    POmodelist.Add(model);
                }
            }
            return View("ViewPurchaseOrders", POmodelist);
        }

        public ActionResult ViewPurchaseOrdersDetails(Guid id)
        {

            ViewPOrderItems POItmz;
            List<ViewPOrderItems> POItemList = new List<ViewPOrderItems>();
            using (var context = new SCMSEntities())
            {
                Model.PurchaseOrder Po = context.PurchaseOrders.SingleOrDefault(p => p.Id == id);
                List<PurchaseOrderItem> POItemz = Po.PurchaseOrderItems.OrderByDescending(p => p.OrderRequestItemId).ToList();
                foreach (PurchaseOrderItem item in POItemz)
                {
                    POItmz = new ViewPOrderItems();
                    POItmz.EntityPOItem = item;
                    POItmz.BudgetLine = context.ProjectBudgets.SingleOrDefault(p => p.Id == item.BudgetLineId).LineNumber;
                    POItmz.ProjectNo = item.ProjectBudget.BudgetCategory.ProjectDonor.ProjectNumber;
                    POItmz.Unitmessue = item.OrderRequestItem != null ? item.OrderRequestItem.Item.UnitOfMeasure.Code : Resources.Global_String_NA;
                    OrderRequestItem orit = item.OrderRequestItem;
                    Item itm = orit != null ? orit.Item : null;
                    POItemList.Add(POItmz);
                }

                ViewPOs model = new ViewPOs();

                model.POEntiy = Po;
                model.supplier = context.Suppliers.SingleOrDefault(p => p.Id == Po.SupplierId).Name;
                if (Po.PaymentTermId != null)
                    model.paymentTerm = context.PaymentTerms.SingleOrDefault(p => p.Id == Po.PaymentTermId).Code;
                if (Po.ShippingTermId != null)
                    model.shippingTerm = context.ShippingTerms.SingleOrDefault(p => p.Id == Po.ShippingTermId).Name;
                model.POItems = POItemList;
                model.deleliveryDate = (DateTime)Po.LatestDeliveryDate;
                model.PODate = (DateTime)Po.PreparedOn;
                model.StaffEntity = context.Staffs.SingleOrDefault(p => p.Id == Po.PreparedBy);
                model.TotalAmount = Po.TotalAmount;
                model.MBValue = Po.MBValue;
                Person ps = model.StaffEntity.Person;
                Designation ds = model.StaffEntity.Designation;
                if ((bool)Po.IsReviewed && Po.ReviewedBy != null)
                {
                    model.ReviewdBy = context.Staffs.SingleOrDefault(p => p.Id == Po.ReviewedBy);
                    var person = model.ReviewdBy.Person;
                    var desg = model.ReviewdBy.Designation;
                    model.ReveiwDate = Po.ReviewedOn.Value;
                }
                if ((bool)Po.IsAuthorized && Po.AuthorizedBy != null)
                {
                    model.AuthorizdBy = context.Staffs.SingleOrDefault(p => p.Id == Po.AuthorizedBy);
                    var person = model.AuthorizdBy.Person;
                    var desg = model.AuthorizdBy.Designation;
                    model.AuthorizDate = Po.AuthorizedOn.Value;
                }

                TenderAnalysi ta = Po.TenderAnalysi;
                if (Po.OrderRequest != null)
                {
                    var or = Po.OrderRequest;
                }
                Location loc = Po.Location;
                ViewBag.Currency = Po.Currency.ShortName;
                if (model.POEntiy.IsReviewed == true)
                    ViewBag.MBCurrency = mbCurrency.ShortName;
                model.CanEdit = (model.POEntiy.IsSubmitted != true && model.POEntiy.IsRejected != true && model.POEntiy.Staff1.Id == currentStaff.Id) ||
                    (model.POEntiy.IsSubmitted && model.POEntiy.IsRejected && model.POEntiy.IsReviewed != true && model.POEntiy.Staff1.Id == currentStaff.Id);

                //Manage approval link
                string actionType = null;
                if (model.POEntiy.IsReviewed == true && model.POEntiy.IsAuthorized == false)
                    actionType = NotificationHelper.authorizationCode;
                else if (model.POEntiy.IsSubmitted && model.POEntiy.IsReviewed == false)
                    actionType = NotificationHelper.reviewCode;
                if (actionType != null)
                    model.CanApprove = notificationService.CanApprove(currentUser, NotificationHelper.poCode, actionType, model.POEntiy.Id);
                else
                    model.CanApprove = false;

                return View("ViewPurchaseOrdersDetails", model);
            }

        }

        [HttpGet]
        public ActionResult AddNewSupplier4PO()
        {
            return View("AddNewSupplier4PO", new USupplier());
        }

        [HttpPost]
        public ActionResult AddNewSupplier4PO(USupplier model)
        {
            Supplier supplier = null;
            supplier = supplierService.GetSupplierByName(model.Name, countryProg.Id);
            if (supplier == null)
            {
                supplier = new Supplier();
                supplier.Name = model.Name;
                supplier.Address = model.Address != null && model.Address.Trim().Length > 0 ? model.Address : Resources.SystemUser_ViewProfile_NotSet.ToUpper();
                supplier.PrimaryPhone = model.PrimaryPhone != null && model.PrimaryPhone.Trim().Length > 0 ? model.PrimaryPhone : Resources.SystemUser_ViewProfile_NotSet.ToUpper();
                supplier.CountryId = countryProg.CountryId;
                supplier.CountryProgrammeId = countryProg.Id;
                supplier.IsApproved = false;
                supplierService.AddSupplier(supplier);
            }
            return RepopulateSupplierList(supplier.Id);
        }

        private ActionResult RepopulateSupplierList(Guid selectedSupplierId)
        {
            StringBuilder supplierDropDown = new StringBuilder();
            string selected = "";
            supplierDropDown.Append("<select data-val=\"true\" data-val-required=\"" + Resources.Global_String_Required + "\" id=\"supplierID\" name=\"supplierID\"><option value=\"\">" + Resources.Global_String_PleaseSelect + "</option>");
            List<Model.Supplier> suppliers = supplierService.GetSuppliers(countryProg.Id);
            foreach (Supplier supplier in suppliers)
            {
                if (supplier.Id.Equals(selectedSupplierId))
                    selected = "selected";
                else
                    selected = "";
                supplierDropDown.Append("<option value=\"" + supplier.Id + "\" " + selected + ">" + supplier.Name + "</option>");
            }
            supplierDropDown.Append("</select>");
            supplierDropDown.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"supplierID\" data-valmsg-replace=\"true\"></span>");
            return Content(supplierDropDown.ToString(), "text/html");
        }

        [HttpGet]
        public ActionResult AddNewLocation4PO()
        {
            ULocation model = new ULocation();
            model.CountrySelect = new SelectList(locationService.CountryObj.GetCountries(), "Id", "Name");
            model.CountryId = countryProg.CountryId;
            return View("AddNewLocation4PO", model);
        }

        [HttpPost]
        public ActionResult AddNewLocation4PO(ULocation model)
        {
            Location location = null;
            location = locationService.GetLocationByName(model.Name, countryProg.Id);
            if (location == null)
            {
                location = new Location();
                location.Name = model.Name;
                location.Description = model.Description;
                location.CountryId = model.CountryId;
                location.CountryProgrammeId = countryProg.Id;
                //location.IsApproved = false;
                locationService.AddLocation(location);
            }
            return RepopulateLocationList(location.Id);
        }

        private ActionResult RepopulateLocationList(Guid selectedLocationId)
        {
            StringBuilder locationDropDown = new StringBuilder();
            string selected = "";
            locationDropDown.Append("<select data-val=\"true\" data-val-required=\"" + Resources.Global_String_Required + "\" id=\"deliveryAddressID\" name=\"deliveryAddressID\"><option value=\"\">" + Resources.Global_String_PleaseSelect + "</option>");
            List<Model.Location> locations = ORService.GetLocations(countryProg.Id);
            foreach (Location location in locations)
            {
                if (location.Id.Equals(selectedLocationId))
                    selected = "selected";
                else
                    selected = "";
                locationDropDown.Append("<option value=\"" + location.Id + "\" " + selected + ">" + location.Name + "</option>");
            }
            locationDropDown.Append("</select>");
            locationDropDown.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"deliveryAddressID\" data-valmsg-replace=\"true\"></span>");
            return Content(locationDropDown.ToString(), "text/html");
        }

        public ActionResult BackDatePO(Guid id)
        {
            Model.PurchaseOrder model = POService.GetPurchaseOrderById(id);
            return View("BackDatePO", model);
        }

        [HttpPost]
        public ActionResult BackDatePO(Model.PurchaseOrder model)
        {
            if (model.PODate > DateTime.Today)
                return ViewPurchaseOrdersDetails(model.Id);
            model.BackDatedBy = currentStaff.Id;
            POService.BackDatePO(model);
            return ViewPurchaseOrdersDetails(model.Id);
        }

        public ActionResult Getattachment(Guid docId)
        {
            Model.AttachedDocument mm = POService.GetDocById(docId);
            //return new FileContentResult(mm.FileContent, mm.ContentType);
            return File(mm.FileContent, mm.ContentType, mm.FileName);


            //byte[] mk = mm.FileContent;
            //System.IO.File.WriteAllBytes(System.Web.HttpContext.Current.Request.PhysicalApplicationPath + "/Content/tmp_reports/" + mm.Name + ".pdf", mk);
            ////string s = Encoding.UTF8.GetString(mk);
            //return Json(new { Status = "OK" });
            //return Content(s);

            // return File(System.IO.File.WriteAllBytes(mm.Name, mm.FileContent));
        }
    }
}
